package pkg

import (
	"errors"
	"fmt"
	"github.com/golang-jwt/jwt/v5"
	"time"
	"userop_bff/global"
)

type TokenPair struct {
	AccessToken  string
	RefreshToken string
}

// @secretKey: JWT 加解密密钥
// @iat: 时间戳
// @seconds: 过期时间，单位秒
// @payload: 数据载体
func GetTokenPair(payload string, accessTokenExpireTime, refreshTokenExpireTime int64) (TokenPair, error) {
	//获取当前的unix时间戳
	currentTime := time.Now().Unix()

	accessTokenClaims := make(jwt.MapClaims)
	accessTokenClaims["exp"] = currentTime + accessTokenExpireTime
	accessTokenClaims["iat"] = currentTime
	accessTokenClaims["payload"] = payload
	accessToken := jwt.New(jwt.SigningMethodHS256)
	accessToken.Claims = accessTokenClaims
	accessTokenString, err := accessToken.SignedString([]byte(global.ServerConfig.JwtConfig.Key))
	if err != nil {
		return TokenPair{}, err
	}

	refreshTokenClaims := make(jwt.MapClaims)
	refreshTokenClaims["exp"] = currentTime + refreshTokenExpireTime
	refreshTokenClaims["iat"] = currentTime
	refreshTokenClaims["payload"] = payload
	refreshToken := jwt.New(jwt.SigningMethodHS256)
	refreshToken.Claims = refreshTokenClaims
	refreshTokenString, err := refreshToken.SignedString([]byte(global.ServerConfig.JwtConfig.Key))
	if err != nil {
		return TokenPair{}, err
	}
	// 返回生成的 TokenPair 结构体，包含 Access Token 和 Refresh Token
	return TokenPair{
		AccessToken:  accessTokenString,
		RefreshToken: refreshTokenString,
	}, nil
}

// 生成一对访问令牌
func GenTokenPair(payload string, accessTokenExpireTime, refreshTokenExpireTime int64) (TokenPair, error) {
	//获取当前的unix时间戳
	currentTime := time.Now().Unix()
	//生成 Access Token的声明 （claims）

	accessTokenClaims := jwt.MapClaims{
		//设置Access Token 的过期时间（exp）
		"exp": currentTime + accessTokenExpireTime,
		//设置Access Token 的签发时间（iat）
		"iat": currentTime,
		//存储额外的有效载荷信息（这里是传入payload）
		"payload": payload,
	}
	accessToken := jwt.NewWithClaims(jwt.SigningMethodHS256, accessTokenClaims)
	accessTokenString, err := accessToken.SignedString([]byte(global.ServerConfig.JwtConfig.Key))
	if err != nil {
		return TokenPair{}, err
	}

	//生成Refresh Token的声明
	refreshTokenClaims := jwt.MapClaims{
		//设置Access Token 的过期时间（exp）
		"exp": currentTime + refreshTokenExpireTime,
		//设置Access Token 的签发时间（iat）
		"iat": currentTime,
		//存储额外的有效载荷信息（这里是传入payload）
		"payload": payload,
	}
	// 使用 HMAC SHA-256 签名方法创建 Refresh Token
	refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshTokenClaims)
	refreshTokenString, err := refreshToken.SignedString([]byte(global.ServerConfig.JwtConfig.Key))
	if err != nil {
		return TokenPair{}, err
	}

	// 返回生成的 TokenPair 结构体，包含 Access Token 和 Refresh Token
	return TokenPair{
		AccessToken:  accessTokenString,
		RefreshToken: refreshTokenString,
	}, nil
}

// 验证访问令牌并提取载荷
func CheckAccessToken(tokenString string) (string, error) {
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		return []byte(global.ServerConfig.JwtConfig.Key), nil
	})
	if err != nil {
		return "", err
	}
	if claims, ok := token.Claims.(jwt.MapClaims); ok {
		return claims["payload"].(string), nil
	}
	return "", errors.New("无效的令牌")
}

// 刷新令牌

// RefreshAccessToken 使用刷新令牌生成新的访问令牌
// @refreshTokenString: 刷新令牌
// @newAccessTokenExpireTime: 新的访问令牌过期时间，单位秒
func RefreshAccessToken(refreshTokenString string, newAccessTokenExpireTime int64) (string, error) {
	token, err := jwt.Parse(refreshTokenString, func(token *jwt.Token) (interface{}, error) {
		return []byte(global.ServerConfig.JwtConfig.Key), nil
	})

	if err != nil {
		return "", err
	}
	//获取当前的unix时间戳
	currentTime := time.Now().Unix()

	if claims, ok := token.Claims.(jwt.MapClaims); ok {
		val := claims["payload"]
		fmt.Println(val, "11111")
		refreshAccessClaims := jwt.MapClaims{
			"exp":     currentTime + newAccessTokenExpireTime,
			"iat":     currentTime,
			"payload": val,
		}
		refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshAccessClaims)
		signedString, err := refreshToken.SignedString([]byte(global.ServerConfig.JwtConfig.Key))
		if err != nil {
			return "", errors.New("无效的载荷")
		}
		return signedString, nil
	}
	return "", err
}
